package com.yungam.other.iot_controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import com.yungam.common.bean.alarm.AlarmDto;
import com.yungam.common.bean.equip.Equipment;
import com.yungam.common.bean.process.ProcessEquipment;
import com.yungam.common.bean.process.ProductProcess;
import com.yungam.common.bean.process.ProductionProcess;
import com.yungam.common.bean.product.ProductionProduct;
import com.yungam.common.bean.work_order.WorkOrderProduct;
import com.yungam.common.response.RetDTO;
import com.yungam.common.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 数控拼焊扫码开始
 * params: [productSn, ip]
 *     *   if : 传递了 productSn 则 验证 该罐号在 work_order_product 表中的『state』是否 = 0
 *     *   else : 查询 work_order_product 表中的『state』为 0 的第一个罐号
 */
@Slf4j
@RestController
@RequestMapping("/imcs_to_iot")
public class ProcessStartController {

    @Resource
    private EquipmentService equipmentService;
    @Resource
    private WorkOrderProductService workOrderProductService;
    @Resource
    private AlarmService alarmService;
    @Resource
    private ProcessEquipmentService processEquipmentService;
    @Resource
    private ProductProcessService productProcessService;
    @Resource
    private ProductionProductService productionProductService;
    @Resource
    private ProductionProcessService productionProcessService;

    @PostMapping("/processStart")
    public RetDTO<?> processStart(@RequestBody Map<String, Object> data) {
        log.info("========= START『iot调用imcs』[数控拼焊扫码开始]=========");
        String json = new Gson().toJson(data);
        log.info("=========『iot数据』{}", json);
        Map<String, Object> ans = Maps.newHashMap();

        String productSn = data.get("productSn") == null ? null : String.valueOf(data.get("productSn")),
                ip = String.valueOf(data.get("ip"));
        Equipment equipment = equipmentService.getOne(new QueryWrapper<Equipment>().eq("equ_ip", ip));
        if (equipment == null) {
            log.error("=========『数控拼版设备不存在』=========");
            return RetDTO.error("数控拼版设备不存在");
        }

        // productSn == null
        if (productSn == null) {
            List<WorkOrderProduct> list = workOrderProductService.list(new QueryWrapper<WorkOrderProduct>().eq("state", 0)
                    .orderByAsc("id"));
            if (list.size() == 0) {
                log.error("=========『当前没有开工的订单, 请联系mes管理员』=========");
                AlarmDto alarmDto = new AlarmDto();
                alarmDto.setTimestamp(new Date().getTime());
                alarmDto.setName("当前没有开工的订单, 请联系mes管理员");
                alarmDto.setLevel(2);
                alarmService.save(alarmDto);
                return RetDTO.error("当前没有开工的订单, 请联系mes管理员");
            }
            productSn = list.get(0).getProductSn();
        }

        // productSn != null 验证 productSn 在 work_order_product 表中的『state』是否 = 0
        WorkOrderProduct wop = workOrderProductService.getOne(new QueryWrapper<WorkOrderProduct>().eq("product_sn", productSn));
        if (wop == null) {
            log.error("=========『罐号不存在』=========");
            return RetDTO.error("罐号不存在");
        }
        if (wop.getState() == 1) {
            log.error("=========『罐号已经使用』=========");
            return RetDTO.error("罐号已经使用");
        }
        // 根据产品代号、设备编号，判断产品工序是否存在
        List<Integer> list = processEquipmentService.list(new QueryWrapper<ProcessEquipment>()
                        .eq("equ_number", equipment.getEquNumber())).stream().map(ProcessEquipment::getProcessId)
                .collect(Collectors.toList());

        ProductProcess pp = null;
        if (list.size() > 0) {
            pp = productProcessService.getOne(new QueryWrapper<ProductProcess>().eq("product_no", wop.getProductNo())
                    .in("process_id", list));
        }
        if (pp == null) {
            log.error("=========『设备对应工序不存在』=========");
            return RetDTO.error("设备对应工序不存在");
        }

        // update || insert 『production_product』
        ProductionProduct product = productionProductService.getOne(new QueryWrapper<ProductionProduct>()
                .eq("product_sn", productSn));
        if (product == null) product = new ProductionProduct();

        product.setProductNo(pp.getProductNo());
        product.setProductSn(productSn);
        product.setState(0);
        product.setStartTime(new Date());
        if (product.getProductionId() == null) productionProductService.save(product);
        else productionProductService.updateById(product);

        // update || insert 『production_process』
        ProductionProcess process = productionProcessService.getOne(new QueryWrapper<ProductionProcess>()
                .eq("product_sn", productSn).eq("process_no", pp.getProcessNo()).eq("equ_no", equipment.getEquNumber()));
        if (process == null) process = new ProductionProcess();

        process.setProductSn(productSn);
        process.setProcessNo(pp.getProcessNo());
        process.setProcessName(pp.getProcessName());
        process.setProductNo(pp.getProductNo());
        process.setEquNo(equipment.getEquNumber());
        process.setState(0);
        process.setStartTime(new Date());
        if (process.getQualityId() == null) productionProcessService.save(process);
        else productionProcessService.updateById(process);

        ans.put("productSn", productSn);
        log.info("========= END『iot调用imcs』[打磨工序结束接口] 调用成功 =========");
        log.info("========= 返回数据 productSn: {} =========", productSn);
        return RetDTO.data(ans);
    }

}
